﻿using StackExchange.Redis;
using System;
using System.Collections.Generic;

namespace Publicuse.DBCore.Redis.CMultiplexer
{
    /// <summary>
    /// Redis连接对象管理
    /// </summary>
    public sealed class CMultiplexerProvider
    {
        private static Dictionary<int, RedisInstance> pInst;

        static CMultiplexerProvider()
        {
            pInst = new Dictionary<int, RedisInstance>();
        }

        public static void AddInstance(int iType, RedisInstance inst)
        {
            if (pInst.ContainsKey(iType))
                return;

            pInst.Add(iType, inst);
        }

        public static RedisInstance GetInstance(int iType)
        {
            if (!pInst.ContainsKey(iType))
                return null;

            return pInst[iType];
        }


        public static Dictionary<int, RedisInstance> GetRedisInstances()
        {
            return pInst;
        }
    };

    /// <summary>
    /// Redis连接实例
    /// </summary>
    public class RedisInstance
    {
        private string server;
        private int port;
        private string password;
        private string connstr;

        public string Server
        {
            get { return server; }
            set
            {
                server = value;
                RendConnection();
            }
        }

        public int Port
        {
            get { return port; }
            set
            {
                port = value;
                RendConnection();
            }
        }

        public string Password
        {
            get { return password; }
            set
            {
                password = value;
                RendConnection();
            }
        }

        public string ConnectionString
        {
            get { return connstr; }
        }

        public RedisInstance()
        {
            this.server = "127.0.0.1";
            this.port = 6379;
        }

        public RedisInstance(string address, int port, string password = null)
        {
            this.server = address;
            this.port = port;
            this.password = password;

            RendConnection();
        }

        private void RendConnection()
        {
            if (string.IsNullOrEmpty(server))
                return;

            this.connstr = string.Format("{0}:{1}", server, port);
            if (!string.IsNullOrEmpty(password))
                this.connstr += ",password=" + password;
        }

        /// <summary>
        /// 连接指定Redis服务
        /// </summary>
        /// <returns></returns>
        public ConnectionMultiplexer GetConnection()
        {
            var st = DateTime.Now.ToString("yyyyMMddHHmmss");
            ConnectionMultiplexer connectionMultiplexer = null;
            if (string.IsNullOrEmpty(connstr))
                return null;

            string msg = string.Empty;
            var stTime = DateTime.Now;
            try
            {
                var cfgRedis = new ConfigurationOptions
                {
                    EndPoints =
                        {
                            { this.Server, this.Port }
                        },
                    ConnectRetry=5,//在初始化 Connect 失败的时候重新尝试进行链接的次数
                    ConnectTimeout = 3600000,//链接超时时间(ms) 1小时 1分钟=6000毫秒
                    KeepAlive = 180,//发送信息以保持sockets在线的间隔时间
                    Password = this.Password,//密码
                    SyncTimeout= 3600000,//同步操作的超时时间(ms) 1分钟=6000毫秒
                    
                    AbortOnConnectFail = false
                };

                connectionMultiplexer = CMultiplexerConnectionHelper.GetInstance().GetConnectionMultiplexer(this.Port, cfgRedis);
            }
            catch (Exception ex)
            {
                var sj = DateTime.Now - stTime;
                var hf = string.Format("连接Reids{4}耗时：{0}时{1}分{2}秒{3}毫秒", sj.Hours, sj.Minutes, sj.Seconds, sj.Milliseconds, connstr);
                msg = "Redis连接-" + st + "|" + this.Port + hf + "|引发异常的方法：" + ex.TargetSite + ex.Message + "|内部异常：" + ex.InnerException + "|异常出现位置：" + ex.StackTrace;
                //LogTools.GetInstance.WriteLogOld("服务器", msg, false);
            }
            return connectionMultiplexer;
        }
    };
}
